<?php declare(strict_types=1);

namespace app\common\service;

use app\admin\service\UserService;
use app\common\constant\RedisKeyConst;
use app\common\lib\Redis\RedisPackage;
use think\facade\Log;

class WechatService
{
    /**
     * @var mixed
     */
    private static $WechatConfig;

    /**
     * @var RedisPackage|\Redis\RedisPackage|null
     */
    private static $redis;

    public function __construct()
    {
        self::$WechatConfig = config('app.wechat');
        self::$redis = RedisPackage::getInstance();
    }

    /**
     * 资料审核发送模板消息
     * @param $userId
     * @param $templateId
     * @param $data
     * @return bool
     */
    public function sendAuditMessage($userId, $templateId, $data): bool
    {
        $openId = $this->getUserOpenId($userId);
        $userProfileKey = RedisKeyConst::getUserProfileKey($userId);
        $nickName = self::$redis::hGet($userProfileKey, 'nickname');

        // 组装模板信息
        $item = [];
        $item['touser'] = $openId;
        $item['template_id'] = $templateId;
        $item['data'] = [
            "thing14" => [
                "value"=> $nickName
            ],
            "phrase1" => [
                "value"=> $data['status'] == 1 ? '认证通过':'拒绝'
            ],
            "thing2" => [
                "value"=> !empty($data['remarks']) ? $data['remarks']:'证件符合要求'
            ],
            "date3" => [
                "value"=> $data['authed_at'] ?? date('Y-m-d H:i:s')
            ],
            "thing17" => [
                "value"=> ($data['status'] == 1 ? '认证通过':'拒绝')
            ]
        ];
        $item['page'] = 'pages/certify/memberCert?scene=subscribe';
        return $this->sendSubscribeMessage($item);
    }

    /**
     * 提现审核发送模板消息
     * @param $userId
     * @param $templateId
     * @param $data
     * @return bool
     */
    public function sendWithdrawMessage($userId, $templateId, $data): bool
    {
        $openId = $this->getUserOpenId($userId);
        $userProfileKey = RedisKeyConst::getUserProfileKey($userId);
        $nickName = self::$redis::hGet($userProfileKey, 'nickname');

        // 组装模板信息
        $item = [];
        $item['touser'] = $openId;
        $item['template_id'] = $templateId;
        $item['data'] = [
            "time5" => [
                "value"=> $data['created_at']
            ],
            "thing8" => [
                "value"=> $nickName
            ],
            "amount1" => [
                "value"=> $data['amount']
            ],
            "phrase2" => [
                "value"=> ($data['handle_status'] == 1) ? "审核通过":($data['handle_status'] == 2 ? '审核不通过':'审核中')
            ],
            "thing9" => [
                "value"=> ($data['handle_status'] == 1) ? "已打款":($data['handle_status'] == 2 ? '拒绝':'审核中')
            ],
        ];
        $item['page'] = 'pages/my/wallet?scene=subscribe';
        return $this->sendSubscribeMessage($item);
    }

    /**
     * 发送订阅消息
     * @param $data
     * @return bool
     */
    public function sendSubscribeMessage($data): bool
    {
        $data['miniprogram_state'] = 'developer'; // 跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
        $accessToken = $this->getAccessToken();
        if (!$accessToken) {
            Log::error("get getAccessToken fun:" .__FUNCTION__);
            return false;
        }
        // 将路径中占位符 %s替换为 $access_token
        $urls = sprintf(self::$WechatConfig['Template_Msg_Url'], $accessToken);
        try {
            $ret = curlPost($urls, json_encode($data));
            $status = json_decode($ret, true);
            if (isset($status['errcode']) && $status['errcode'] == 0) {
                Log::info("sendSubscribeMessage ok:" .json_encode($data));
                return true;
            } else {
                Log::error("sendSubscribeMessage error errcode:{$status['errcode']} errmsg:{$status['errmsg']}");
                return false;
            }
        } catch (\Exception $e) {
            Log::error("sendSubscribeMessage error:" .$e->getMessage());
            return false;
        }
    }

    /**
     * 获取 AccessToken
     * @return mixed
     */
    public function getAccessToken(): mixed
    {
        $redis = RedisPackage::getInstance();
        $accessTokenKey = RedisKeyConst::CONFIG_APP_ACCESS_TOKEN;
        $ttl  = $redis::ttl($accessTokenKey); // -2:不存在 -1:存在但没有设置过期时间
        if ($ttl == -2) { // 不存在
            try {
                $AppID = self::$WechatConfig['AppId'];
                $AppSecret = self::$WechatConfig['AppSecret'];
//                $StableAccessTokenUrl = sprintf(self::$WechatConfig['StableAccessTokenUrl'], $AppID, $AppSecret);
//                $item = json_decode(file_get_contents($StableAccessTokenUrl), true);
                $ret = curlPost("https://api.weixin.qq.com/cgi-bin/stable_token", json_encode(['grant_type'=>'client_credential', 'appid'=>$AppID, 'secret'=>$AppSecret]));
                $item = json_decode($ret, true);
                if (isset($item['access_token']) && isset($item['expires_in'])) {
                    $redis::set($accessTokenKey, $item['access_token'], $item['expires_in']-200);
                    return $item['access_token'];
                } else {
                    Log::error("getAccessToken error:" .$ret);
                    return false;
                }
            } catch (\Exception $e) {
                Log::error("getAccessToken error:". $e->getMessage());
                return false;
            }
        } else {
            return $redis::get($accessTokenKey);
        }
    }

    /**
     * 获取用户openid
     * @param $userId
     * @return void
     */
    public function getUserOpenId($userId){
        $redis = RedisPackage::getInstance();
        $userOpenIdKey = RedisKeyConst::getUserOpenIdKey($userId);
        if ($redis::exists($userOpenIdKey)) {
            $openId = $redis::hGet($userOpenIdKey, 'openid');
        } else {
            $openId = (new UserService())->_getUserOpenId($userId);
            if ($openId) {
                $redis::hSet($userOpenIdKey, 'openid', $openId);
            }
        }

        return $openId;
    }
}